#!/bin/bash

# 定时数据库备份脚本
# 适用于 cron 定时任务
set -e

# 配置变量
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
BACKUP_DIR="$PROJECT_DIR/backups"
LOG_DIR="$PROJECT_DIR/logs"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="person_development_${DATE}.sql"
LOG_FILE="$LOG_DIR/backup_$(date +%Y%m).log"

# 创建必要的目录
mkdir -p "$BACKUP_DIR"
mkdir -p "$LOG_DIR"

# 日志函数
log() {
    local level=$1
    shift
    local message="$*"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
}

log_info() {
    log "INFO" "$@"
}

log_error() {
    log "ERROR" "$@"
}

log_success() {
    log "SUCCESS" "$@"
}

# 错误处理函数
handle_error() {
    local exit_code=$?
    log_error "备份脚本执行失败，退出码: $exit_code"
    log_error "备份文件: $BACKUP_FILE"
    exit $exit_code
}

# 设置错误处理
trap handle_error ERR

log_info "开始数据库备份..."
log_info "备份目录: $BACKUP_DIR"
log_info "日志文件: $LOG_FILE"

# 从环境变量或配置文件读取数据库信息
DB_HOST=${MYSQL_HOST:-"139.159.190.115"}
DB_PORT=${MYSQL_PORT:-"3308"}
DB_USER=${MYSQL_USER:-"root"}
DB_PASS=${MYSQL_PASSWORD:-"Xx@123456"}
DB_NAME=${MYSQL_DATABASE:-"person_development"}

log_info "备份数据库: $DB_NAME"
log_info "数据库地址: $DB_HOST:$DB_PORT"

# 检查 mysqldump 命令是否存在
if ! command -v mysqldump &> /dev/null; then
    log_error "mysqldump 命令未找到，请安装 MySQL 客户端"
    exit 1
fi

# 测试数据库连接
log_info "测试数据库连接..."
if ! mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" -e "SELECT 1" "$DB_NAME" &>/dev/null; then
    log_error "无法连接到数据库，请检查连接参数"
    exit 1
fi
log_success "数据库连接测试成功"

# 执行备份
log_info "开始执行数据库备份..."
BACKUP_START_TIME=$(date +%s)

if mysqldump -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" \
    --single-transaction \
    --routines \
    --triggers \
    --events \
    --add-drop-database \
    --add-drop-table \
    --set-gtid-purged=OFF \
    "$DB_NAME" > "$BACKUP_DIR/$BACKUP_FILE"; then
    
    BACKUP_END_TIME=$(date +%s)
    BACKUP_DURATION=$((BACKUP_END_TIME - BACKUP_START_TIME))
    
    log_success "备份成功: $BACKUP_FILE (耗时: ${BACKUP_DURATION}秒)"
    
    # 压缩备份文件
    log_info "压缩备份文件..."
    if gzip "$BACKUP_DIR/$BACKUP_FILE"; then
        COMPRESSED_FILE="$BACKUP_FILE.gz"
        COMPRESSED_SIZE=$(ls -lh "$BACKUP_DIR/$COMPRESSED_FILE" | awk '{print $5}')
        log_success "压缩完成: $COMPRESSED_FILE (大小: $COMPRESSED_SIZE)"
    else
        log_error "压缩失败"
        exit 1
    fi
    
    # 删除7天前的备份文件
    log_info "清理旧备份文件..."
    OLD_BACKUPS=$(find "$BACKUP_DIR" -name "*.sql.gz" -mtime +7 2>/dev/null || true)
    if [ -n "$OLD_BACKUPS" ]; then
        echo "$OLD_BACKUPS" | while read -r file; do
            if [ -f "$file" ]; then
                rm "$file"
                log_info "删除旧备份: $(basename "$file")"
            fi
        done
    else
        log_info "没有需要清理的旧备份文件"
    fi
    
    # 显示备份文件信息
    log_info "备份文件信息:"
    ls -lh "$BACKUP_DIR/$COMPRESSED_FILE" | tee -a "$LOG_FILE"
    
    # 显示磁盘使用情况
    DISK_USAGE=$(df -h "$BACKUP_DIR" | tail -1 | awk '{print $5}')
    log_info "备份目录磁盘使用率: $DISK_USAGE"
    
else
    log_error "备份失败"
    exit 1
fi

log_success "数据库备份完成！"
log_info "备份文件: $BACKUP_DIR/$COMPRESSED_FILE"
log_info "日志文件: $LOG_FILE"

# 如果磁盘使用率超过80%，发出警告
DISK_USAGE_NUM=$(echo "$DISK_USAGE" | sed 's/%//')
if [ "$DISK_USAGE_NUM" -gt 80 ]; then
    log_error "警告: 备份目录磁盘使用率过高 ($DISK_USAGE)，请及时清理"
fi

exit 0